package com.qf.smsplatform.interfaces.service.impl;

import com.qf.smsplatform.common.constants.CacheConstants;
import com.qf.smsplatform.common.constants.RabbitMQConstants;
import com.qf.smsplatform.common.constants.SourceConstants;
import com.qf.smsplatform.common.enums.SmsEnum;
import com.qf.smsplatform.common.exception.SmsException;
import com.qf.smsplatform.common.model.StandardSubmit;
import com.qf.smsplatform.common.util.MobileFormatUtil;
import com.qf.smsplatform.common.util.SnowFlakeUtil;
import com.qf.smsplatform.interfaces.client.CacheClient;
import com.qf.smsplatform.interfaces.dto.SmsDTO;
import com.qf.smsplatform.interfaces.service.InterfaceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * projectName: smsplatform
 *
 * @author: MaTianWei
 * time: 2021/8/11 20:24
 * description:接口模块鉴权接口
 */
@Service
@Slf4j
public class InterfaceServiceImpl implements InterfaceService {

    @Autowired
    private CacheClient cacheClient;
    @Autowired
    private SnowFlakeUtil snowFlakeUtil;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void checkSmsParam(SmsDTO smsDTO) {


        //----------1.ClientID----------
        //1.1是否为空
        String clientID = smsDTO.getClientID();
        if (StringUtils.isEmpty(clientID)) {
            //clientID有问题
            log.info("[接口模块-下行接口] 认证错误:clientID clientID = {} ", clientID);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_CLIENTID);
        }
        //1.2缓存模块查询客户信息
        Map map = cacheClient.hGetAll(CacheConstants.CACHE_PREFIX_CLIENT + clientID);
        //1.3如果客户信息是否为null
        if (map == null || map.size() == 0) {
            //client有问题
            log.info("[接口模块-下行接口] 认证错误:clientID clientID = {} ", clientID);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_CLIENTID);
        }


        //----------2.pwd----------
        //2.1非空并且等于当前客户的pwd
        String pwd = smsDTO.getPwd();
        if (StringUtils.isEmpty(pwd) || !pwd.equals(map.get("pwd"))) {
            //pwd有问题
            log.info("[接口模块-下行接口] 密码错误 pwd = {}", pwd);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_PWD);
        }


        //TODO----------3.IP(白名单) 已完成----------
        //3.1获取当前客户的白名单IP
        String smsDTOIp = smsDTO.getIp();   //自己的
        String ipaddress = (String) map.get("ipaddress");   //redis数据库的
        String[] ips = ipaddress.split(",");
        //3.2判断当前客户端真实IP是否满足白名单
        boolean flag = false;
        for (String ip : ips) {
            if (smsDTOIp.equals(ip)) {
                flag = true;
                break;
            }
        }
        if (flag == false) {
            log.info("[接口模块-下行接口] ip不在白名单 smsDTOIp = {}", smsDTOIp);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_IP_ERROR);
        }


        //TODO----------4.content 短信内容,超过100个字,分多条发送 已完成----------
        String content = smsDTO.getContent();
        //4.1短信内容非空
       if(StringUtils.isEmpty(content)){
           //如果为空
           log.info("[接口模块-下行接口] 短信内容,不能为空! content = {}", content);
           throw new SmsException(SmsEnum.INTERFACE_PARAMETER_CONTENT_ERROR);
       }



            //----------5.mobile 手机号校验----------
            String mobiles = smsDTO.getMobile();
            //5.1手机号是否为空,并且只处理后100个手机号
            if (StringUtils.isEmpty(mobiles)) {
                //mobile有问题
                log.info("[接口模块-下行接口] 手机号错误,不能为空! mobiles = {}", mobiles);
                throw new SmsException(SmsEnum.INTERFACE_PARAMETER_MOBILE_EMPTY);
            }

            String[] mobileArray = mobiles.split(",");
            Set<String> okMobile = new HashSet<>();
            Set<String> errorMobile = new HashSet<>();
            for (String mobile : mobileArray) {
                //5.2判断手机号格式(正则校验) 整理出错误的手机号
                if (MobileFormatUtil.checkMobile(mobile)) {
                    //手机号正确
                    //5.3整理出正确的手机号,整理100个手机号(为了方便测试整理10个)
                    if (okMobile.size() < 10) {
                        okMobile.add(mobile);
                    } else {
                        errorMobile.add(mobile);
                    }
                } else {
                    //手机号格式错误
                    errorMobile.add(mobile);
                }
            }







            //TODO----------6.SrcID下行编号 已完成----------
            String srcID = smsDTO.getSrcID();
            //6.1判断SrcID是否为数值
            //用到StringUtils这个工具类 isNumeric会认为空字符串为非法数字，isNumericSpace则认为空字符串也是数字。
                boolean numFlag = StringUtils.isNumericSpace(srcID);
                if (!numFlag){
                    log.info("[接口模块-下行接口] SrcID下行编号,不能为空! srcID = {}", srcID);
                    throw new SmsException(SmsEnum.INTERFACE_PARAMETER_SRCID_ERROR);
            }



        //----------7.封装消息 StandardSubmit----------
            //每一条短信对应一条消息
            for (String mobile : okMobile) {
                //判断短信内容是否超过100个字符
                int contentLength = content.length();
                //超过100,分条发送
                //超过限制,需要将短信内容分条发送
                int count = contentLength / 100;
                if (count == 0) {
                    count = 1;
                }
                if (count * 100 < contentLength) {
                    count++;
                }
                //当前一条短信需要分几条发送
                for (int i = 0; i < count; i++) {
                    StandardSubmit submit = new StandardSubmit();
                    //7.1利用雪花算法生成全局唯一标识
                    long sequenceId = snowFlakeUtil.nextId();
                    //7.2计算短信文本
                    String messageContent = null;
                    if (i == count - 1) {
                        messageContent = content.substring(i * 100, contentLength);
                    } else {
                        messageContent = content.substring(i * 100, (i + 1) * 100);
                    }
                    //7.3封装Submit的基本数据  sequenceId  clientID  srcSequenceId  destMobile  messageContent  source
                    submit.setSequenceId(sequenceId + "");
                    submit.setClientID(Integer.valueOf(clientID));
                    submit.setSrcSequenceId(srcID == null ? null : Long.parseLong(srcID));
                    submit.setDestMobile(mobile);
                    submit.setMessageContent(messageContent);
                    submit.setSource(SourceConstants.HTTP);
                    //7.4发送到RabbitMQ的队列
                    rabbitTemplate.convertAndSend(RabbitMQConstants.TOPIC_PRE_SEND, submit);
                }
            }
        }
    }